home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 9
/
FM Towns Free Software Collection 9.iso
/
t_os
/
tool
/
tetujin
/
src
/
poly.c
< prev
next >
Wrap
Text File
|
1994-11-16
|
11KB
|
590 lines
/* polygon
1994 5/4
*/
#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include <mos.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include "poly.h"
#define ENDSW 2 /* 終了ボタンはマウス右 */
#define CANCELSW 3 /* キャンセルボタンはマウス左右ボタン */
static int sw = 0,cx = 0,cy = 0; /* MOUSE data */
static int pn = 0; /* POLYGON point counter */
static int ax1=0,ay1=0,ax2=0,ay2=0; /* POLYGON area min & max */
static short int poly[POLYMAX+2][2]; /* POLYGON point data */
static char para[256]; /* PARAM */
static char *ework ;
static char *buffer ;
static int xlen ;
static int ylen ;
static int color ;
static int ( *setDisplay )() ;
static int initFlag = 0 ;
/* init */
/* 引数 EGBワーク,ポリゴン作業領域,横,縦,カーソルを表示内に入れるための関数 */
polygon_rectangle_init( char *egbWork, char *buf,
int x, int y, int c, int ( *f )() )
{
ework = egbWork ;
buffer = buf ;
xlen = x ;
ylen = y ;
color = c ;
setDisplay = f ;
initFlag = 1 ;
return NOERR ;
}
/* polygon 1 */
polygon_1st( int *lux, int *luy, int *rdx, int *rdy )
{
int x0,y0,ydis,d,loop,i,add,dini,numini;
double num,deg;
int ret ;
ax1 = 0; ay1 = 0; ax2 = 0; ay2 = 0;
*lux = ax1; *luy = ay1;
*rdx = ax2; *rdy = ay2;
if( initFlag == 0 )return -1 ;
MOS_rdpos(&sw,&cx,&cy); /* この場におよんで押してないのはやる気なし */
if( sw != 1 )
{
return -1 ;
}
pn = 0; /* pn = 0 */
polygon_rectangle_clear() ;
poly[0][0] = cx;
x0 = cx;
ax1 = cx;
ax2 = cx;
d=0;
poly[0][1] = cy;
y0 = cy;
ay1 = cy;
ay2 = cy;
mouseInit() ;
plygn0:
ret = mouse( 1, 1 ) ;
plygn1:
if( sw == CANCELSW )
{
while( sw )
{ /* マウスボタンリリースまで待つ */
int x, y ;
MOS_rdpos(&sw,&x,&y);
}
polygon_2nd() ;
polygon_rectangle_clear() ;
pn = 0 ;
return -1 ;
}
if( ret )sw = ENDSW ; /* ダブルクリックなら終わる */
if( (cx == x0) && (cy == y0) && (sw == 1) )goto plygn0;
plygn2:
if( pn < POLYMAX ){
poly[pn + 1][0] = cx;
poly[pn + 1][1] = cy;
polygonDispLine( pn ) ;
pn = pn + 1;
}
ydis = cy - y0;
if( ydis == 0 )goto plygn3;
num = xlen*y0 + x0;
deg = xlen + ( (double)cx - (double)x0 ) / (double)ydis;
if( ydis < 0 )deg = -deg;
loop = ydis;
if( loop < 0 )loop = -loop;
if( d * ydis >= 0 ){
loop = loop - 1;
num = num + deg;
}
for(i=0;i<=loop;i++){
add = (int)( num + .5 ) ;
BYTE( buffer + (add >> 3) )
= BYTE( buffer + (add >> 3) ) ^ ( 0x80 >> (add % 8) ) ;
num = num + deg ;
}
if( d == 0 ){
dini = ydis ;
numini = xlen*y0 + x0 ;
}
d = 1;
if( ydis < 0 )d = -1;
plygn3:
if( ax1 > cx )ax1 = cx;
if( ax2 < cx )ax2 = cx;
if( ay1 > cy )ay1 = cy;
if( ay2 < cy )ay2 = cy;
x0 = cx;
y0 = cy;
if( sw == 1 ){
for(i=0;i<100;i++);
goto plygn0;
}
if( sw == ENDSW ){
while( sw )
{ /* マウスボタンリリースまで待つ */
int x, y ;
MOS_rdpos(&sw,&x,&y);
if( sw == CANCELSW )break ;
}
if( sw == CANCELSW )goto plygn1 ;
sw = 0;
cx = poly[0][0];
cy = poly[0][1];
goto plygn2;
}
if( d*dini < 0 ){
add = numini ;
BYTE( buffer + (add >> 3) )
= BYTE( buffer + (add >> 3) ) ^ ( 0x80 >> (add % 8) ) ;
}
polygonBufConnect( ay1, ay2 );
*lux = ax1; *luy = ay1;
*rdx = ax2; *rdy = ay2;
return NOERR;
}
/* polygon 2 */
polygon_2nd()
{
int i ;
if( initFlag == 0 )return -1 ;
if( pn == 0 )return -1;
for( i=0 ; i<pn ; i++ )
{
polygonDispLine( i ) ;
polygonBufOrLine( i ) ;
}
return 0;
}
/* rectangle 1 */
rectangle_1st( int *lux, int *luy, int *rdx, int *rdy )
{
int x,y;
ax1 = 0; ay1 = 0; ax2 = 0; ay2 = 0;
*lux = ax1; *luy = ay1;
*rdx = ax2; *rdy = ay2;
if( initFlag == 0 )return -1 ;
MOS_rdpos(&sw,&cx,&cy); /* この場におよんで押してないのはやる気なし */
if( sw != 1 )
{
return -1 ;
}
pn = 0; /* pn = 0 */
polygon_rectangle_clear() ;
ax1 = cx;
ay1 = cy;
if( boxMouse() )
return -1 ;
ax2 = cx;
ay2 = cy;
if( ax1 > ax2 )
{
int temp ;
temp = ax1 ;
ax1 = ax2 ;
ax2 = temp ;
}
if( ay1 > ay2 )
{
int temp ;
temp = ay1 ;
ay1 = ay2 ;
ay2 = temp ;
}
for( y=ay1 ; y<=ay2 ; y++ )
{
for( x=ax1 ; x<=ax2 ; x++ )
{
int add ;
add = xlen*y + x ;
BYTE( buffer + (add >> 3) )
= BYTE( buffer + (add >> 3) ) | ( 0x80 >> (add % 8) ) ;
}
}
*lux = ax1; *luy = ay1;
*rdx = ax2; *rdy = ay2;
return NOERR ;
}
/* rectangle 2 */
rectangle_2nd()
{
EGB_color(ework,0,color);
EGB_paintMode(ework,0x2);
EGB_writeMode(ework,4);
WORD(para + 0) = ax1;
WORD(para + 2) = ay1;
WORD(para + 4) = ax2;
WORD(para + 6) = ay2;
EGB_rectangle(ework,para);
EGB_writeMode(ework,0);
EGB_paintMode(ework,0x222);
return NOERR ;
}
/* read */
polygon_rectangle_read( int x, int y )
{
int add ;
if( (x < 0) || (x >= xlen) )return 0 ;
if( (y < 0) || (y >= ylen) )return 0 ;
add = xlen * y + x ;
if( BYTE( buffer + (add >> 3) ) & ( 0x80 >> (add % 8) ) )
return 1 ;
else
return 0 ;
}
/* polygon buffer clear */
polygon_rectangle_clear()
{
int i, n ;
n = (xlen*ylen) >> 3 ;
for( i=0 ; i<n ; i++ )
BYTE( buffer + i ) = 0 ;
return NOERR ;
}
static polygonDispLine( n )
{
EGB_color(ework,0,color);
EGB_paintMode(ework,0x222);
EGB_writeMode(ework,4);
WORD(para + 0) = 2;
WORD(para + 2) = poly[n][0];
WORD(para + 4) = poly[n][1];
WORD(para + 6) = poly[n+1][0];
WORD(para + 8) = poly[n+1][1];
EGB_unConnect(ework,para);
WORD(para + 0) = 2;
WORD(para + 2) = poly[n+1][0];
WORD(para + 4) = poly[n+1][1];
WORD(para + 6) = poly[n+1][0];
WORD(para + 8) = poly[n+1][1];
EGB_unConnect(ework,para);
EGB_writeMode(ework,0);
return NOERR ;
}
static polygonBufOrLine( n )
{
int i, count ;
int x0, y0, x1, y1, xd, yd ;
int absxd, absyd ;
double xadd, yadd ;
double xdouble, ydouble ;
x0 = poly[n][0];
y0 = poly[n][1];
x1 = poly[n+1][0];
y1 = poly[n+1][1];
xd = x1 - x0 ;
yd = y1 - y0 ;
if( xd > 0 )
absxd = xd ;
else
absxd = - xd ;
if( yd > 0 )
absyd = yd ;
else
absyd = - yd ;
if( (absxd == 0) && (absyd == 0) )
{
int add ;
add = xlen*y0 + x0 ;
BYTE( buffer + (add >> 3) )
= BYTE( buffer + (add >> 3) ) | ( 0x80 >> (add % 8) ) ;
return NOERR ;
}
if( absxd >= absyd )
{
yadd = (double)yd / (double)xd ;
if( xd > 0 )
xadd = 1 ;
else
{
xadd = - 1 ;
yadd = - yadd ;
}
count = absxd ;
}
else
{
xadd = (double)xd / (double)yd ;
if( yd > 0 )
yadd = 1 ;
else
{
yadd = - 1 ;
xadd = - xadd ;
}
count = absyd ;
}
xdouble = x0 ;
ydouble = y0 ;
for( i=0 ; i<count ; i++ )
{
int x, y, add ;
x = xdouble + .5 ;
y = ydouble + .5 ;
add = xlen*y + x ;
if( add < (xlen * ylen) )
BYTE( buffer + (add >> 3) )
= BYTE( buffer + (add >> 3) ) | ( 0x80 >> (add % 8) ) ;
xdouble += xadd ;
ydouble += yadd ;
}
return NOERR ;
}
static polygonBufConnect( y1, y2 )
{
int i, n1, n2, k, d, e ;
n1 = xlen*y1 ;
n2 = xlen*( y2 + 1 ) ;
k = 0 ;
for( i=n1 ; i<n2 ; i++ )
{
d = BYTE( buffer + (i >> 3) ) ;
e = 0x80 >> (i % 8) ;
if( d & e )
k ^= 1 ;
if( k )
BYTE( buffer + (i >> 3) ) = d | e ;
}
return NOERR ;
}
static int swmemory, cxmemory, cymemory ;
/* マウスイニシャライズ */
static int mouseInit()
{
swmemory = -100000 ;
cxmemory = -100000 ;
cymemory = -100000 ;
return NOERR ;
}
/*
backmode 0:マウスボタン開放時にreturn 1:マウスボタン押した時にreturn
dspmode 0:なにも表示しない 1:コネクトラインを表示
戻り値 0:ダブルクリックでない 1:ダブルクリックである
*/
static int mouse( int backmode, int dspmode ) /* mouse */
{
int x,y,cx0,cy0,mdsp,dummy;
int doubleClick, ret ;
EGB_color(ework,0,color);
EGB_paintMode(ework,0x222);
EGB_writeMode(ework,4);
cx0 = -1; cy0 = -1; mdsp = 1; dummy = -1; doubleClick = 0 ;
if( mdsp ){
MOS_rdpos(&sw,&cx0,&cy0);
setDisplay( cx0, cy0 ) ;
if( dspmode )mousesub(dspmode,cx,cy,cx0,cy0);
}
mouse1:
MOS_rdpos(&sw,&x,&y);
setDisplay( x, y ) ;
if( sw )goto mouse2;
if( doubleClick == 0 )doubleClick = 1 ;
if( (cx0 == x) && (cy0 == y) )goto mouse1;
doubleClick = -1 ;
if( mdsp == 0 ){
cx0 = x;
cy0 = y;
}
if( dspmode )mousesub(dspmode,cx,cy,cx0,cy0);
mdsp = mdsp ^ 1;
goto mouse1;
mouse2:
if( mdsp && dspmode )mousesub(dspmode,cx,cy,cx0,cy0);
if(
(doubleClick > 0) && (x == cxmemory) && (y == cymemory) &&
(sw == 1) && (swmemory == 1)
)
ret = 1 ;
else
ret = 0 ;
swmemory = sw ;
if( doubleClick )
{
cxmemory = x ;
cymemory = y ;
}
else if( (cx != x) || (cy != y) )
{
cxmemory = -100000 ;
cymemory = -100000 ;
}
cx = x;
cy = y;
if( backmode )goto mouse3;
while( dummy ){
MOS_rdpos(&dummy,&x,&y);
setDisplay( x, y ) ;
}
mouse3:
EGB_writeMode(ework,0);
return ret ;
}
static mousesub(int dspmode,int cx,int cy,int cx0,int cy0) /* 特殊カーソル */
{
switch( dspmode ){
case 0:
break;
case 1:
WORD(para + 0) = 2;
WORD(para + 2) = cx;
WORD(para + 4) = cy;
WORD(para + 6) = cx0;
WORD(para + 8) = cy0;
EGB_unConnect(ework,para);
break;
}
return 0;
}
/* BOX用マウス */
static int boxMouse()
{
int x,y,cx0,cy0,mdsp;
int ret ;
EGB_color(ework,0,color);
EGB_paintMode(ework,0x2);
EGB_writeMode(ework,4);
cx0 = -1; cy0 = -1; mdsp = 1; ret = 0 ;
if( mdsp ){
MOS_rdpos(&sw,&cx0,&cy0);
if( sw > 1 )ret = -1 ;
boxMousesub(cx,cy,cx0,cy0);
setDisplay( cx0, cy0 ) ;
}
mouse1:
MOS_rdpos(&sw,&x,&y);
if( sw == 0 )goto mouse2;
if( sw > 1 )ret = -1 ;
if( (cx0 == x) && (cy0 == y) )goto mouse1;
if( mdsp == 0 ){
cx0 = x;
cy0 = y;
}
boxMousesub(cx,cy,cx0,cy0);
setDisplay( cx0, cy0 ) ;
mdsp = mdsp ^ 1;
goto mouse1;
mouse2:
if( ret )
{
if( mdsp )boxMousesub(cx,cy,cx0,cy0);
setDisplay( cx0, cy0 ) ;
}
else
{
if( mdsp == 0 )boxMousesub(cx,cy,cx0,cy0);
setDisplay( cx0, cy0 ) ;
}
cx = cx0;
cy = cy0;
mouse3:
EGB_writeMode(ework,0);
EGB_paintMode(ework,0x222);
return ret ;
}
static boxMousesub(int cx,int cy,int cx0,int cy0) /* BOXカーソル */
{
WORD(para + 0) = cx;
WORD(para + 2) = cy;
WORD(para + 4) = cx0;
WORD(para + 6) = cy0;
EGB_rectangle(ework,para);
return 0;
}